package cumeo89.chii.client.ui;

import com.google.gwt.dom.client.Node;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.Widget;

public class TwoColumnPanel extends ComplexPanel implements ExtendedPanel {

	Element leftList;
	Element rightList;

	public TwoColumnPanel() {
		Element table = createLayoutTable();
		Element tbody = DOM.getFirstChild(table);

		Element row = DOM.createTR();

		Element leftCell = createLayoutCell();
		leftList = DOM.createElement("ul");
		DOM.appendChild(leftCell, leftList);
		DOM.appendChild(row, leftCell);

		Element rightCell = createLayoutCell();
		rightList = DOM.createElement("ul");
		DOM.appendChild(rightCell, rightList);
		DOM.appendChild(row, rightCell);

		DOM.appendChild(tbody, row);

		setElement(table);
	}

	private Element createLayoutCell() {
		Element cell = DOM.createTD();
		DOM.setElementAttribute(cell, "width", "50%");
		DOM.setElementAttribute(cell, "vAlign", "top");
		return cell;
	}

	private Element createLayoutTable() {
		Element table = DOM.createTable();
		/*
		 * Make it a layout table
		 */
		DOM.setElementAttribute(table, "width", "100%");
		DOM.setElementAttribute(table, "border", "0");
		DOM.setElementAttribute(table, "cellspacing", "0");
		DOM.setElementAttribute(table, "cellpadding", "0");

		Element tbody = DOM.createTBody();
		DOM.appendChild(table, tbody);

		return table;
	}

	@Override
	public void add(Widget child) {
		Element li = DOM.createElement("li");
		DOM.appendChild(rightList, li);
		super.add(child, li);

		doBalance();
	}

	public void insert(Widget newChild, Widget beforeChild) {
		insert(newChild, getWidgetIndex(beforeChild));
	}

	public void insert(Widget child, int beforeIndex) {
		Element li = DOM.createElement("li");
		/*
		 * Have a look at com.google.gwt.user.client.ui.VerticalPanel.java
		 */
		int left = DOM.getChildCount(leftList);
		if (beforeIndex > left) {
			DOM.insertChild(rightList, li, beforeIndex - left);
		} else {
			DOM.insertChild(leftList, li, beforeIndex);
		}
		super.insert(child, li, beforeIndex, false);

		doBalance();
	}

	@Override
	public boolean remove(Widget w) {
		/*
		 * Have a look at com.google.gwt.user.client.ui.VerticalPanel.java
		 */
		Element li = DOM.getParent(w.getElement());
		boolean removed = super.remove(w);
		if (removed) {
			Element ul = DOM.getParent(li);
			DOM.removeChild(ul, li);
		}
		return removed;
	}

	private void doBalance() {
		int right = DOM.getChildCount(rightList), left = DOM
				.getChildCount(leftList), balance = (left + right) / 2;

		for (; right > balance; right--) {
			/*
			 * Move items from right to left
			 */
			Element li = DOM.getFirstChild(rightList);
			rightList.removeChild(li);
			DOM.appendChild(leftList, li);
		}

		for (; right < balance; right++) {
			/*
			 * Move items from right to left
			 */
			Element li = (Element) leftList.getLastChild();
			leftList.removeChild(li);
			DOM.insertChild(rightList, li, 0);
		}
	}

	public void replace(Widget oldChild, Widget newChild) {
		newChild.removeFromParent();

		int index = getChildren().indexOf(oldChild);
		getChildren().remove(oldChild);
		getChildren().insert(newChild, index);

		Element oldElement = oldChild.getElement();
		Element newElement = newChild.getElement();
		Node parent = oldElement.getParentNode();
		parent.replaceChild(newElement, oldElement);

		adopt(newChild);
	}

}
